import React from 'react';
import type { Settings as LayoutSettings } from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import { notification } from 'antd';
import type { RequestConfig, RunTimeLayoutConfig } from 'umi';
import { history } from 'umi';
import RightContent from '@/components/RightContent';
import Footer from './components/Footer';
import type {
  ResponseError,
  RequestInterceptor,
  ResponseInterceptor,
  RequestOptionsInit,
} from 'umi-request';
import { getToken, serverUrl } from '@/utils/utils';
import { getcurrentUser } from './services/login';
import defaultSettings from '../config/defaultSettings';
// import type { MenuDataItem } from '@ant-design/pro-layout';
const loginPath = '/login/page';
const avatarUrl = 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png';

/**
 * 获取用户信息比较慢的时候会展示一个 loading
 */
export const initialStateConfig = {
  loading: <PageLoading />,
};

export async function getInitialState(): Promise<{
  settings?: LayoutSettings;
  currentUser?: API.CurrentUser;
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
  const fetchUserInfo = async () => {
    try {
      const msg = await getcurrentUser();
      const currentUser = {
        name: msg.data.name,
        avatar: avatarUrl, // data.photoFileUrl,
      };
      return currentUser;
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };

  // 如果是登录页面，不执行
  if (history.location.pathname !== loginPath) {
    const currentUser = await fetchUserInfo();
    return {
      fetchUserInfo,
      currentUser,
      settings: defaultSettings,
    };
  }
  return {
    fetchUserInfo,
    settings: defaultSettings,
  };
}

export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录，重定向到 login
      if (getToken() === 'token' && location.pathname !== loginPath) {
        notification.warning({
          description: '你的认证信息已失效，请重新登录',
          message: '登录过期',
        });
        history.push(loginPath);
      }
    },
    menuHeaderRender: undefined,
    // menuDataRender: (menuData: MenuDataItem[]) => {
    //   // 开启权限校验 递归循环menuData，删除拥有id且没有权限的路由
    //   let menu: MenuDataItem[];
    //   if (initialState?.currentUser?.navigationList) {
    //     menu = handleMenu(menuData, initialState?.currentUser!.navigationList || []);
    //   } else {
    //     menu = [];
    //   }
    //   return menu;
    //   // return menuData;
    // },
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    ...initialState?.settings,
  };
};

const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  405: '请求方法不被允许。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};

/**
 * 异常处理程序
 */
const errorHandler = (error: ResponseError) => {
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;

    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  }

  if (!response) {
    notification.error({
      description: '您的网络发生异常，无法连接服务器',
      message: '网络异常',
    });
  }
  throw error;
};

// 全局请求拦截
const requestInterceptor: RequestInterceptor = (url: string, options: RequestOptionsInit) => {
  return {
    url,
    options: {
      ...options,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        token: getToken(),
      },
    },
  };
};

const responseInterceptor: ResponseInterceptor = async (
  response: Response,
  options: RequestOptionsInit,
) => {
  // 文件流下载
  if (options.responseType === 'blob') {
    const filename = response.headers.get('content-disposition'); // 下载后文件名
    const fileName = filename?.split(';')[1].split('filename=')[1];
    const res = await response.clone();
    res.blob().then((blob) => {
      const objectURL = URL.createObjectURL(blob);
      // 创建隐藏的可下载链接
      const eleLink = document.createElement('a');
      eleLink.download = fileName || '文件';
      eleLink.style.display = 'none';
      eleLink.href = objectURL;
      // 模拟点击下载
      document.body.appendChild(eleLink);
      eleLink.click();

      // 下载完成移除
      document.body.removeChild(eleLink);
    });
    return response;
  }

  const res = await response.clone().json();

  if (res.code === 40003) {
    history.push(loginPath);
    localStorage.removeItem('token');
    notification.warning({
      description: '您的登录过期，请重新登录',
      message: '登录过期',
    });
    res.data = undefined;
  }
  if (res.code === (40000 | 40002 | 40004)) {
    history.push(loginPath);
    localStorage.removeItem('token');
    res.data = undefined;
  }

  if (res.code !== 10000) {
    notification.error({
      description: '网络请求失败',
      message: res.message,
    });
    res.data = undefined;
  }

  // 如果data为空 强制返回空数组 页面只判断请求成功与否
  if (res.data === null) {
    res.data = [];
  }

  return res;
};

export const request: RequestConfig = {
  prefix: `${serverUrl()}`,
  errorHandler,
  requestInterceptors: [requestInterceptor],
  responseInterceptors: [responseInterceptor],
  errorConfig: {
    adaptor: (res: any) => {
      return {
        ...res,
      };
    },
  },
};
